package com.haizheng.sockte;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * @program: Demo
 * @description: 服务端server
 * @author: Hz~
 * @create: 2019-02-18 11:39
 **/
public class SocketServer {
    /**
     * 获取系统的绝对路径，例：E:\Code\IDEA\Demo
     */
    public static String WEB_ROOT = System.getProperty("user.dir") + "\\" + "web";

    /**
     * 用于存放本次请求的静态页面名称
     */
    public static String url = "";

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        OutputStream ops = null;
        try {
            serverSocket = new ServerSocket(8080);
            while (true) {
                socket = serverSocket.accept();
                is = socket.getInputStream();
                ops = socket.getOutputStream();
                //获取HTTP协议的请求部分，截取客户端要访问的资源名称，将这个资源名称赋值给url
                parse(is);
                //发送静态资源
                sendStaticResource(ops);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                is.close();
                is = null;
            }
            if (null != ops) {
                ops.close();
                ops = null;
            }
            if (null != socket) {
                socket.close();
                socket = null;
            }
        }
    }

    /**
     * 获取HTTP协议的请求部分，截取客户端要访问的资源名称，将这个资源名称赋值给url
     *
     * @param is 输入流
     */
    private static void parse(InputStream is) throws IOException {
        //定义变量存放http协议请求部分数据
        StringBuffer sb = new StringBuffer(2048);
        //定义一个数组，存放http协议请求部分数据
        byte[] buffer = new byte[2048];
        //定义一个变量i，代表读取数组到数组中之后数据量的大小
        int i = -1;
        //读取客户端发送过来的数据，将数据读取到字节数组buffer中，i代表读取数据量的大小
        i = is.read(buffer);
        //循环遍历数组，将数组中的数据追加到sb中
        for (int j = 0; j < i; j++) {
            sb.append((char) buffer[j]);
        }
        parseUrl(sb.toString());
    }

    /**
     * 截取客户端要请求的资源路径demo1.html，赋值给url
     * GET /Demo/demo1.html HTTP/1.1
     *
     * @param sb
     */
    private static void parseUrl(String sb) {
        int index1, index2;
        //获取htto请求部分第一个空格的位置
        index1 = sb.indexOf(" ");
        if (index1 != -1) {
            index2 = sb.indexOf(" ", index1 + 1);
            if (index2 != -1) {
                url = sb.substring(index1, index2).substring(7);
            }
        }
    }


    /**
     * 发送静态资源
     *
     * @param ops 输出流
     */
    private static void sendStaticResource(OutputStream ops) throws IOException {
        byte[] buffer = new byte[2048];
        FileInputStream fis = null;
        try {
            File file = new File(WEB_ROOT, url);
            if (file.exists()) {
                ops.write("HTTP/1.1 200 OK\n".getBytes());
                ops.write("Server: Apache-Coyote/1.1\n".getBytes());
                ops.write("Content-Type: text/html;charset=UTF-8\n"
                        .getBytes());
                ops.write("\n".getBytes());
                fis = new FileInputStream(file);
                int ch = fis.read(buffer);
                while (ch != -1) {
                    ops.write(buffer, 0, ch);
                    ch = fis.read(buffer);
                }
                ops.flush();
            } else {
                String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
                        + "Content-Type: text/html\r\n"
                        + "Content-Length: 23\r\n" + "\r\n"
                        + "<h1>File Not Found</h1>";
                ops.write(errorMessage.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != fis) {
                fis.close();
                fis = null;
            }
        }
    }


}
